# Create your views here.
# coding: utf-8

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse
from django.contrib import messages

from main.authfuncs import get_user_profile, auth_user_required
from main.views import get_default_context
from models import Poll, PollVariant, Vote

from datetime import datetime
import random
import simplejson as json

def check_vote_cookie(func, *args, **kwargs):
    def wrapper(request, *args, **kwargs):
        vote_key = request.COOKIES.get('vote_key', Poll.gen_vote_key())
        kwargs['vote_key'] = vote_key
        response = func(request, *args, **kwargs)
        response.set_cookie('vote_key', vote_key)
        return response
    
    return wrapper

@check_vote_cookie
def poll_list(request, **kwargs):
    c = get_default_context(request)
    c['title'] = u'Список голосовалок'
    polls = Poll.objects.all()
    c['polls'] = polls
    return render_to_response('poll/poll_list.html', c)

@check_vote_cookie
def poll(request, **kwargs):
    c = get_default_context(request)
    poll_id = kwargs.get('poll_id', None)
    try: poll_id = int(poll_id)
    except ValueError: 
        return HttpResponseRedirect(reverse('poll_list'))
    poll = get_object_or_404(Poll, pk = poll_id)
    c['title'] = poll.title
    c['poll'] = poll
    poll_variants = PollVariant.objects.filter(poll = poll)
    c['poll_variants'] = poll_variants
    vote_variant = request.GET.get('poll_{0}'.format(poll_id), None)
    if vote_variant:
        try: vote_variant = int(vote_variant)
        except ValueError: vote_variant = None
    if vote_variant:
        vote = Vote(poll = poll, poll_variant_id = vote_variant, key = kwargs['vote_key']) 
        result = vote.save()
        if result:
            c['poll_variants'] = None
            c['vote_result'] = u'Ага!'
            c['poll_results'] = get_poll_results(poll.id)
        else:
            c['vote_result'] = u'Да вы уже голосовали, батенька!'
    response = render_to_response('poll/poll.html', c)
    response.set_cookie('vote_key', '123')
    return response

def get_poll_results(poll_id):
    votes = Vote.objects.filter(poll = poll_id)
    result = {}
    for one in votes:
        variant_id = one.poll_variant.id
        if not result.has_key(variant_id):
            result[variant_id] = {'count':0, 'text': one.poll_variant.text}
        result[variant_id]['count'] += 1
    res_list = []
    for key in result.keys():
        res_list.append(result[key])
    return res_list

def jsonp_response(func, *args, **kwargs):
    def wrapper(request, *args, **kwargs):
        result = func(request, *args, **kwargs)
        callback = request.GET.get('callback', None)
        if callback and type(callback).__name__ in 'unicodestr':
            result = "{0}({1});".format(callback, result)
        return HttpResponse(result)
    return wrapper

@check_vote_cookie
@jsonp_response
def get_poll_data(request, **kwargs):
    result = {'result': 'error', 'variants': [], 'poll': {}, 'action': 'undefined', 'vote_key': kwargs.get('vote_key')}
    vote_key = kwargs.get('vote_key')
    poll_id = kwargs.get('poll_id', None)
    poll = None

    if poll_id:
        try: poll_id = int(poll_id)
        except ValueError: poll_id = None
        try:
            poll = Poll.objects.get(id = poll_id)
        except Poll.DoesNotExist:
            result['result'] = 'error'
            result['explain'] = 'does_not_exist'
    
    if not poll_id:
        query = """
        SELECT id, user_id, created, title, answer_type, closed, active FROM poll_poll WHERE poll_poll.id NOT IN
            (SELECT DISTINCT poll_id FROM poll_vote WHERE poll_vote.key = "{0}")
        AND poll_poll.closed = 0 AND poll_poll.active =1
        """.format(vote_key)
        poll_set = list(Poll.objects.raw(query))
        if len(poll_set): 
            poll = random.choice(poll_set)
            result['action'] = 'vote'
        else:
            # если пользователь проголосовал за все что можно
            result['action'] = 'view_only'
            poll = random.choice( Poll.objects.filter(active = True) )
    if poll:
        result['poll'] = {'id': poll.id, 'title': poll.title, 'answer_type': poll.answer_type}
        poll_variants = PollVariant.objects.filter(poll = poll)
        for one in poll_variants:
            result['variants'].append({'variant_id': one.id, 'text': one.text, 'votes': one.votes})

        try: votes = list(Vote.objects.filter(poll = poll, key = vote_key))
        except Vote.DoesNotExist: vote = None
        if len(votes): result['action'] = 'view_only'
        else: result['action'] = 'vote'

    result['result'] = 'success'
    result_data = json.dumps(result)
    
    return result_data

# @check_vote_cookie
# @jsonp_response
# def recieve_vote(request, **kwargs):
#     result = {'result': 'error', 'variants': [], 'poll': {}, 'action': 'undefined', 'vote_key': kwargs.get('vote_key')}
#     poll_id = kwargs.get('poll_id', None)
#     try: poll_id = int(poll_id)
#     except ValueError: poll_id = None
#     variant_id = request.get('variant_id', None)
#     try: variant_id = int(variant_id)
#     except ValueError: variant_id = None
#     if poll_id and variant_id:
#         try: poll = Poll.objects.get(id = poll_id)
#         except Poll.DoesNotExist: poll = None
#         if poll:
#             try: vote_variant = PollVariant.objects.get(id = variant_id, poll = poll)
#             except PollVariant.DoesNotExist: vote_variant = None
#             result['poll'] = {'id': poll.id, 'title': poll.title}
#             if vote_variant:
#                 vote = Vote(poll = poll, poll_variant = vote_variant, key = kwargs['vote_key']) 
#                 if vote.save():
#                     result['result'] = 'success'
#                     poll_variants = PollVariant.objects.filter(poll = poll)
#                     for one in poll_variants:
#                         result['variants'].append({'variant_id': one.id, 'text': one.text, 'votes': one.votes})
#                 else:
#                     result['explain'] = 'already voted'
#             else:
#                 result['explain'] = 'wrong answer id'
#         else:
#             result['explain'] = 'wrong poll id'
#     return json.dumps(result)

@check_vote_cookie
@jsonp_response
def recieve_vote(request, **kwargs):
    result = {'result': 'error', 'variants': [], 'poll': {}, 'action': 'undefined', 'vote_key': kwargs.get('vote_key')}
    poll_id = kwargs.get('poll_id', None)
    try: poll_id = int(poll_id)
    except ValueError: poll_id = None
    try: poll = Poll.objects.get(id = poll_id, active = True, closed = False)
    except Poll.DoesNotExist: poll = None
    if poll:

        poll_variants = list(PollVariant.objects.filter(poll = poll))
        if not len(poll_variants): result['explain'] = 'no answer variants!'
        # вот тут следовало бы посмотреть, может пользователь уже проголосовал тут, но пока так.

        if poll.answer_type == 'single':
            vote = None
            if len(poll_variants):
                for one in poll_variants:
                    if request.GET.get( 'v_{0}'.format(one.id), None ):
                        vote = Vote(poll = poll, poll_variant = one, key = kwargs['vote_key'])
                        break
                if vote:
                    if vote.save():
                        result['result'] = 'success'
                    else:
                        result['explain'] = 'already voted'
                else:
                    result['explain'] = 'wrong answer id'
        
        if poll.answer_type == 'multi':
            if len(poll_variants):
                voted = None
                for answer_num, one in enumerate(poll_variants):
                    if request.GET.get( 'v_{0}'.format(one.id), None):
                        vote = Vote(poll = poll, poll_variant = one, multianswer_num = answer_num, key = kwargs['vote_key'])
                        if not vote.save():
                            result['explain'] = 'already voted'
                            assert False
                            break

                        else:
                            voted = True
                if not voted:
                    result['explain'] = 'wrong answer ids'
                else:
                    result['result'] = 'success'

        if result['result'] == 'success':
            result['action'] == 'view_only'
            result['poll'] = {'id': poll.id, 'title': poll.title}
            for one in poll_variants: result['variants'].append({'variant_id': one.id, 'text': one.text, 'votes': one.votes})

    return json.dumps(result)
